﻿/// <reference path="jquery-1.4.2.js" />

$(function() {

	$('input').each(function() {
		var self = $(this);
		if (self.hasClass('login-ipt')) {
			var ele = "<span class='ipt-span'></span>";
			self.wrap(ele);
			if (self.hasClass('ipt-nosel')) {
				self.parent('span.ipt-span').addClass('nosel');
			} else {
				self.focus();
			}
		}

		if (self.hasClass('textClass')) {
			var ele = "<span class='text-spanClass'></span>";
			self.wrap(ele);
		}
	});

//	$("input.myWdate")
//			.live('focus', function() {
////				WdatePicker({
////					dateFmt : 'yyyy-MM-dd HH:mm:ss',
////					autoPickDate : true
////				});
//				$(this).datetimepicker({
//					timeFormat:'hh:mm:ss'
//				});
//			})
//			.each(
//					function() {
//						var imgbtn = '<img name="dateImgButton" style="margin-left:2px;" src="images/datePicker.png" width="16px" height="16px" align="absmiddle"/>';
//						$(imgbtn).insertAfter(this);
//					});


	$('a.button').each(function() {
		var self = $(this);
		self.wrapInner('<span/>');

	});

	$('input.login-ipt').live('focus', function() {
		$(this).removeClass('ipt-nosel');
		$(this).parent('span.ipt-span').removeClass('nosel');
	}).live('focusout', function() {
		$(this).addClass('ipt-nosel');
		$(this).parent('span.ipt-span').addClass('nosel');
	});

	
	// 提交数组格式设置
	$.ajaxSettings.traditional = true;
	$.ajaxSettings.cache = false;
	// ajax请求登录重定向
	$(window).ajaxSend(function(evt, request, settings) {
		if (!settings.dataType || settings.dataType == 'json') {
			var oldfunc = settings.success;
			settings.success = function(data) {
				if (data && data.data && data.data._url)
					window.location = data.data._url;
				else
					oldfunc(data);
			}

		}

	});

	$('#exportSearch').click(
			function() {
				var self = $(this);
				var url = this.href
						+ '?'
						+ $.param(self.parents('.TableRegion').find(':input')
								.SerializeElements());
				window.open(url);
				return false;
			});
	// $("a.export").click(function() {

	// var self = $(this);
	// var url = this.href + '?' +
	// $.param(self.parents('.TableRegion').find(':input').SerializeElements());
	// window.open(url);
	// return false;
	//   
	// });

	$(':input').focus(function() {
		$(this).addClass('focus');
	}).blur(function() {
		$(this).removeClass('focus');
	});
	$('dl.dlf,dl.dlf>dt,dl.dlf>dd').each(function() {
		$(this).addClass('inlineBlock inline');
	});
	$('ul.ul-datalist>li>dl>dt,ul.ul-datalist>li>dl>dd').each(function() {
		$(this).addClass('inlineBlock inline');
	});

	$('input:submit:not(:has(".login"))').addClass('normal');

/*	// 时间设置
	$.datepicker.setDefaults({
		autoSize : true,
		dateFormat : "yyyy-MM-dd",
		changeMonth : true,
		changeYear : true,
		yearRange : 'c-100:c+10'
	});
	$.datepicker.setDefaults($.datepicker.regional['zh-CN']);*/
	// $.fn.getContraryDate = function() {
	// var isMin = false;
	// var targetInput;
	// var limitName = $(this).attr("name");
	// if (limitName) {
	// var i = limitName.lastIndexOf('.Start');
	// if (i > 0) {
	// isMin = true;
	// limitName = limitName.substr(0, i);
	// targetInput = $('input:[name="' + limitName + '.End' + '"]');
	// } else {
	// i = limitName.lastIndexOf('.End');
	// isMin = false;
	// limitName = limitName.substr(0, i);
	// targetInput = $('input:[name="' + limitName + '.Start' + '"]');
	// }
	// }
	// if (!limitName) {
	// limitName = $(this).attr('maxdate');
	// if (limitName) {
	// isMin = false;
	// targetInput = $('input:[mindate="' + limitName + '"]');
	// } else {
	// limitName = $(this).attr('mindate');
	// if (limitName) {
	// isMin = true;
	// targetInput = $('input:[maxdate="' + limitName + '"]');
	// }
	// }
	// }
	// return { isMin: isMin, targetInput: targetInput };
	// };
	// var limitDate = function(selectedDate, isdatetime) {
	// // var options = $(this).getContraryDate();
	// // var isMin = options.isMin;
	// // var targetInput = options.targetInput;

	// // if (targetInput.length == 0) return;
	// // var date = $(this).datepicker("getDate");
	// // if (!isdatetime)
	// // targetInput.datepicker("option", isMin ? "minDate" : "maxDate", date);
	// // else
	// // targetInput.datetimepicker("option", isMin ? "minDate" : "maxDate",
	// date);
	// };
	// $('input[tag="date"]').datepicker(/*{ onSelect: limitDate
	// }*/).attr('readonly', true);
	// $('input[tag="datetime"]').attr('style', 'width:150px;').datetimepicker({
	// clockType: 24
	// , onSelect: function(selecteddate) {
	// limitDate.apply(this, [selecteddate, true]);
	// }

	// }).attr('readonly', true);

	// 反序列化字符串
	$.StringToJson = function(str) {
		var qsobj = {};
		var thisqs = str.split('?')[1];

		if (thisqs) {
			var pairs = thisqs.split('&');
			for ( var i = 0; i < pairs.length; i++) {
				var pair = pairs[i].split('=');
				qsobj[pair[0]] = pair[1];
			}
		}
		return qsobj;
	};

	// a Button 效果
	// $('a.Button').each(function() {
	// var css = $(this).removeClass('Button').attr('class');
	// $(this).addClass('Button');
	// var content = $(this).html();
	// $(this).empty().append('<span class="icon ' + css +
	// '"/>').append($('<span class="content"/>').html(content));
	// });

	$('div.topOperRegion>a.tb-btn:odd').each(function() {
		$('<span class="tb-btn-split"></span>').insertBefore(this);
	});

	// 调试Log
	$.TraceEnabled = $.IsDebug = $('#_divDebug').length > 0;
	$.Trace = function(str) {
		$('#_divDebug').append(str + "<br />");
	};

	// 取消超链接的虚线框
	$("a").focus(function() {
		this.blur();
	});

	// form输入验证
	$('form').submit(function() {
		$(this).validate();
	});

	$('a.submit').live('click', function() {
		// $.waiting.show("正在保存数据，请稍后...");
		$(this).parents('form').submit();
		return false;
	});

	// Ajax情况下的Form验证
	$('form').bind('form-submit-validate',
			function(event, a, $form, options, veto) {
				if (!$form.validate())
				{
					veto.veto=true;
					return false;
				}
				$.waiting.show('正在提交数据......');
				var oldsuccess = options.success;
				options.success = function() {
					oldsuccess.apply($form, arguments);
					$.waiting.hide();
				};
			});

//	$.extend($, {
//		ajaxSubmit : {
//			options : {
//				beforeSubmit : function(arr, $form, options) {
//					if (!$form.validate())
//						return false;
//					$.waiting.show('正在提交数据......');
//					var oldsuccess = options.success;
//					options.success = function() {
//						oldsuccess.apply($form, arguments);
//						// $.waiting.hide();
//					};
//					return true;
//				}
//			}
//		}
//	});

	// 全选复选框
	$('.datalist>thead>tr>td:first>:checkbox').live(
			'click',
			function() {
				var checked = $(this).attr('checked');
				if (checked) {
					$('.datalist>tbody>tr>td:first-child>:checkbox').attr(
							'checked', true);
				} else {
					$('.datalist>tbody>tr>td:first-child>:checkbox')
							.removeAttr('checked');
				}
			});

	$.InitFlash = function() {
		// 加载flash
		$('*[swf]').each(
				function() {
					var self = $(this);
					var fvars = self.attr('flashvars') || '';
					fvars = fvars.replace('{IP}', window.location.protocol
							+ "//" + window.location.host);
					self.flash({
						swf : self.attr('swf'),
						flashvars : fvars,
						height : self.attr('swfheight') || 320,
						width : self.attr('swfwidth') || 480,
						AllowScriptAccess : "always",
						Allowfullscreen : "true"
					});
				});
	};
	$.InitFlash();

	// ========================查询分页=================================//
	// 排序
	$('.datalist thead td[sort]').live('click', function() {
		var self = $(this);

		var oDataTable = $(this).parents('.datalist').parent();
		var strId = oDataTable.attr('id');
		var oAction = $('#' + strId.substr(0, strId.length - 4));
		// 排序的字段
		var dataColumn = $(this).attr('sort');
		if (!dataColumn)
			return false;

		var query = oAction.data('query');

		// 获取上一次排序的值
		var oldColumn = "";
		var bIsasc = true;
		if (query.OrderBy) {
			var arr = query.OrderBy.split(" ");
			oldColumn = arr[0];
			bIsasc = arr[1] == 'asc';
		}

		if (oldColumn == dataColumn)
			bIsasc = !bIsasc;
		var strOrder = (bIsasc ? "asc" : "desc");
		query.OrderBy = dataColumn + " " + strOrder;
		query.PageIndex = 1;
		oAction.data('query', query);
		window.loadpage(oAction);
	});
	// 重新加载当前页
	$.fn.reloadPage = function() {
		window.loadpage(this);
	};
	// 查询并转到第一页
	$.fn.search = function() {
		$(this).click();
	};

	$('a.searchbtn')
			.each(
					function() {
						var self = $(this);
						var oDataTable = $('#' + this.id + "Data");
						var pagedata = oDataTable.children();
						var oPage = $('#' + this.id + "Page");
						var query = {};
						query.pageindex = 1;
						query.pagesize = pagedata.attr("pagesize");
						self.data('query', query);

						// 创建加载页面的方法
						if (!window.loadpage) {
							window.loadpage = function(ele) {
								var self = $(ele);
								if (self.length == 0)
									return;
								var oDataTable = $('#' + self.attr('id')
										+ "Data");
								var oPage = $('#' + self.attr('id') + "Page");
								var query = self.data('query');
								oDataTable
										.load(
												self.attr('href'),
												query,
												function() {
													var data = oDataTable.children();
													oPage.pages('changepage',data.attr("pageindex"),
																	data.attr("recordcount"));

													// 显示排序信息
													if (query.OrderBy) {
														var arr = query.OrderBy
																.split(" ");
														var oldColumn = arr[0];
														var strOrder = ((arr[1] == 'asc') ? 'asc'
																: 'desc');
														$('thead td[sort="'+ oldColumn+ '"]',data)
															.addClass(strOrder).append('<img src="/Content/Images/'+ strOrder+ '.png"/>');
													}
													self.trigger('ajaxload');
													stripe();

												});
							};
						}

						oPage.pages({
							pageindex : pagedata.attr("pageindex"),
							total : pagedata.attr("recordcount"),
							max : 10,
							pagesize : query.pagesize,
							onpage : function(ui) {
								var query = self.data('query');
								query.pageindex = ui.index;
								self.data('query', query);
								window.loadpage(self);
							}
						});

					});

	// 查询搜索
	$('a.searchbtn').click(
			function() {
				var self = $(this);

				var items = $(':input', self.parent()).SerializeElements();
				var dateCtls = $('input[tag="date"][name$=".End"]', self
						.parent());
				dateCtls.each(function() {
					if ($.trim($(this).val()) != '') {
						var date = $(this).datepicker("getDate");
						date.setDate(date.getDate() + 1);
						var str = $.datepicker.formatDate(
								$.datepicker._defaults.dateFormat, date);
						items[this.name] = str;
					}
				});

				var query = $.extend({}, self.data("query"), items, {
					pageindex : 1
				});
				self.data('query', query);
				window.loadpage(this);
				return false;
			});

	// ========================查询分页结束=================================//

	// 点击隐藏
	$(':checkbox.checkhide').bind('click change', function() {
		var checked = $(this).attr('checked');
		if ($(this).hasClass('reverse'))
			checked = !checked;
		if (checked)
			$('*[forid="' + this.id + '"]').show();
		else
			$('*[forid="' + this.id + '"]').hide();
	});

	$(':checkbox.checkhide').each(function() {
		$(this).triggerHandler('click');
	});

	// 弹出层显示ajax信息
	var popmove = function() {
		var self = $(this);
		self.die('mousemove', popmove);
		var aid = self.attr('id');
		var pop = $('#' + aid + 'Pop');
		var loadEle;
		if (pop.hasClass('loadcontent')) {
			loadEle = pop;
		} else {
			loadEle = $('.loadcontent', pop);
		}
		if (loadEle.attr('onloading')) {
			return false;
		} else {
			loadEle.waiting().attr('onloading', true).load(this.href,
					function() {
						loadEle.removeAttr('onloading');
					});
		}
		pop.offset(self.offset()).css('zIndex', self.zIndex() + 1).show();
		pop.one('mouseleave', function() {
			$(this).hide();
		});
		return false;
	};
	$('a.popshow').live('mousemove', popmove);

	$.fn.DialogForm = function(beforeOpenFunc) {
		$($(this).attr('rel')).show();
		$($(this).attr('rel')).draggable();
/*		if($.browser.msie) {
			$($(this).attr('rel')).appendTo("body");
		}*/

		$(this).overlay({
			 mask : {
			 color : '#456786',
			 loadSpeed : 100,
			 opacity : 0.9
			 },
			fixed:false,
			left : 'center',
			top : 'center',
			api : 'true',
			closeOnClick : false,
			closeOnEsc : true,
			oneInstance : false,
			// effect: 'apple',
			// expose : '#004C7D',
			onBeforeLoad : function() {
				if ($.isFunction(beforeOpenFunc))
					beforeOpenFunc();
			}

		});
		$(this).data('overlay').load();
	}

	var alertDlg;
	$.ActionResponse = function(icontype, title, content, callback,cancelcallback) {
		//$overlay =$('#tipDlgOverlay');
		$overlay = $('<div class="tipDlg hidden" id="tipDlgOverlay"><h3>title</h3><div class="content"><p>提示框内容</p></div><div class="dlg-bottom"><a href="#" name="okBtn" class="dlg-button"> 确定 </a><a href="#" name="cancelBtn" class="dlg-button"> 关闭 </a></div>').prependTo(document.body);
		if (alertDlg) {
			$overlay.removeData('overlay');
			alertDlg = null;
		}
		$overlay =$('#tipDlgOverlay');
		$overlay.draggable();
		if (title == '')
			title = '提示';
		$('h3',$overlay).text(title);
		$('p',$overlay).text(content);
		switch (icontype) {
		case 'success':
			$('p', $overlay).removeClass().addClass('success');
			break;
		case 'error':
			$('p', $overlay).removeClass().addClass('error');
			break;
		case 'alert':
			$('p', $overlay).removeClass().addClass('infomation');
			break;
		default:
			$('p', $overlay).removeClass().addClass('infomation');
		}
		
		alertDlg = $overlay.zIndex(30040).overlay({
			fixed:false,
			left : 'center',
			top : 'center',
			api : 'true',
			closeOnClick : false,
			closeOnEsc : false,
			oneInstance : false
		});
		if (callback) {
			
			$('a[name="okBtn"]',$overlay).unbind('click').bind('click',function(){
				alertDlg.close();
				callback();
				return false;
			});
		}
		else{
			$('a[name="okBtn"]',$overlay).attr('style','display:none');
		}
		$('a[name="cancelBtn"]',$overlay).unbind('click').bind('click',function(){
			alertDlg.close();
			if (cancelcallback)
				cancelcallback();
			return false;
			
		});
		alertDlg.load();
	};
	// //等待状态
	var eleWaitingOverlay;
	$.waiting = {
		show : function(msg) {
			/*if (!msg) {
				msg = "正在加载中，请稍后......";
			}
			var ele = $('#waitingOverlay');
			ele.text('').append(msg);
			if (eleWaitingOverlay) {
				$(ele).removeData('overlay');
			}
			eleWaitingOverlay = $(ele).overlay({
				mask : {
					color : '#456786',
					loadSpeed : 200,
					opacity : 0.6
				},
				fixed:false,
				closeOnClick : false,
				closeOnEsc : false,
				left : 'center',
				top : 'center',
				api : 'true',
				oneInstance : false,
				// effect: 'apple',
				expose : '#004C7D',
				load : true
			});*/
		$.blockUI();
			try{
			$(".blockOverlay").zIndex(30031);
			$(".blockMsg ").zIndex(30032);
			}catch(e){}
		},
		hide : function() {
			//eleWaitingOverlay.close();
			$.unblockUI();
		}
	};
	var eleUserListOverlay;

	$.popUserList = {
		show : function(url,name, value, callback) {
			var datalist = $('.popUserList>.userlist');
			if (eleUserListOverlay) {
				$('.popUserList').removeData('overlay');
			}
			$('.popUserList').draggable();
			if(name != null && value != null && name != '' && value != ''){
				$('.popUserList a.searchbtn').attr('href',url+'?'+name+'='+value);
			}else{
				$('.popUserList a.searchbtn').attr('href',url);
			}
				
			$('.popUserList a.searchbtn').search();
			if ($.isFunction(callback)) {
				$('.popUserList>a[name="popUserListSave"]').unbind('click').click(function() {
					// 序列化选中的值
					var row = $(
							'table.table_data_list>tbody>tr>td>:radio:checked',
							$('#tbluserlistData'));
					if (row.length > 0) {
						callback($.parseJSON(row.attr('data')));
					}
					eleUserListOverlay.close();
					return false;
				});
				$('.popUserList>a[name="closeMe"]').unbind('click').click(function() {
					eleUserListOverlay.close();
					return false;
				});
			}

			eleUserListOverlay = $('.popUserList').zIndex(20031).show().overlay({
				/*mask : {
					// color : '#456786',
					loadSpeed : 200,
					opacity : 0.8,
					zIndex : 200003
				},*/
				fixed:false,
				left : 'center',
				top : 'center',
				api : 'true',
				// effect: 'apple',
				oneInstance : false,
				// expose : '#004C7D',
				load : true
			});


		},
		hide : function() {
			eleUserListOverlay.close();
		}
	};
	// $.fn.waiting = function(msg) {
	// if (!msg) {
	// msg = "正在加载中，请稍后......";
	// }
	// return $(this).empty().append('<img src="/Content/Images/waiting.gif"
	// /><span>' + msg + '</span>');
	// };

	var initTableLayout = function() {

		var self = $('div.topOperRegion:not(:has(a))')
				.next('div.datacontainer');
		$('table.datalist:first', self).attr('style', 'border-top:0');
		$('div.topOperRegion:not(:has(a))').hide();
	}

	var stripe = $.stripe = function() {
		$('.datalist>tbody>tr:odd').children('td').addClass('alt');
		initTableLayout();
		// datalist数据表格鼠标悬停变色
		$('.datalist>tbody>tr>td').live("mouseover", function() {
			$(this).parent('tr').children('td').addClass('over');
		}).live('mouseout', function() {
			$(this).parent('tr').children('td').removeClass('over');
		});

		$('.datalist>tbody>tr:odd>td').live(
				"mouseover",
				function() {
					$(this).parent('tr').children('td').removeClass('alt')
							.addClass('over');
				}).live(
				'mouseout',
				function() {
					$(this).parent('tr').children('td').removeClass('over')
							.addClass('alt');
				});
		// $('div.TableRegion').removeShadow().dropShadow({ blur: 1, swap:
		// false, opacity: .5, color: "#999" });

		$('.datalist thead td[sort]').mousedown(function() {
			$(this).addClass('active');
		}).mouseup(function() {
			$(this).removeClass('active');
		});

		// 按钮title提示
		$('a.Edit').attr('title', "编辑");
		$('a.Add').attr('title', "新增");
		$('a.Del').attr('title', "删除");
		$('a.Disabled').attr('title', '禁用');
		$('a.Enabled').attr('title', '启用');
		$('a.ImageAudit').attr('title', '审核');
		$('a.Password').attr('title', '修改密码');
		$('a.ImageReSend').attr('title', '重发');
		$('a.Meet').attr('title', '会见');
		$('a.View').attr('title', '查看');
		$('a.ImageSearch').attr('title', '查询');
		$('a.Reply').attr('title', '回复');
	};
	$.tip = function() {
		$('*[tip]').each(function() {
			var str = $.trim($(this).text());
			var len = parseInt($(this).attr("tip"));
			$(this).attr("title", str).removeAttr("tip");
			if (str.length > len) {
				$(this).text(str.substr(0, len) + "...");
			}
		});
	};
	var initInput = function() {
		var vdt = $(':input[required],select[required]').parent('dd')
				.prev('dt');
		$('label', vdt).before('<span class="required">*</span>');

		$(
				':input[required],:input[datatype],textarea[maxlength], :input[date],input[tag^="date"]')
				.focus(function() {
					$(this).InputTip();
				}).blur(function() {
					$(this).validateele();
				});

		$(':input[maxlength]').keypress(function() {
			var self = $(this);
			var len = self.attr('maxlength');
			if (len) {
				var str = self.val();
				if (str.length > len) {
					self.validatemsg("最多允许输入" + len + "个字符");
					return false;
				} else {
					self.validatemsg("", true);
				}

			}
		});

	};

	$.fn.SerializeElements = function(skipempty) {
		var items = {};
		this.each(function() {
			var fieldname = $(this).attr('datafield') || this.name;
			if (fieldname) {
				var self = $(this);
				if (self.is(':checkbox') || self.is(':radio')) {
					if (self.attr('checked'))
						items[fieldname] = $(this).val();
				} else {
					var val = self.val();
					if (!self.is(':input')) {
						val = val || $.trim(self.text());
					}
					if (val.length == 0 && skipempty)
						return;
					items[fieldname] = val;
				}
			}
		});
		return items;
	};

	$.fn.validatemsg = function(str, success) {

		var ele = this.parent();
		ele.find('span.ErrorTip,span.InputTip').remove();
		if (success) {
			// ele.append($(' <span class="noteCheck true"></span>'));
			$(this).removeClass("inputError");
			return false;
		} else {
			if (this.attr('alert')) {
				$.ActionResponse('error', '提示', this.attr('alert'));
			} else
				this.after('<span class="ErrorTip">' + str + '</span>');
		}
		$(this).addClass("inputError");
		return true;

	};
	$.fn.resetvalidate = function() {
		this.find('span.ErrorTip').remove();
		return this;
	};
	$.fn.removevalidatemsg = function() {
		var ele = this.parent();
		ele.find('span.ErrorTip').remove();
	}
	$.validate = {};
	$.validate.regexEnum = {
		intege : "^-?[0-9]\\d*$", // 整数
		intege1 : "^[1-9]\\d*$", // 正整数
		intege2 : "^-[1-9]\\d*$", // 负整数
		num : "^([+-]?)\\d*\\.?\\d+$", // 数字
		num1 : "^[1-9]\\d*|0$", // 正数（正整数 + 0）
		num2 : "^-[1-9]\\d*|0$", // 负数（负整数 + 0）
		decmal : "^([+-]?)\\d*\\.\\d+$", // 浮点数
		decmal1 : "^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$", // 正浮点数
		decmal2 : "^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$", // 负浮点数
		decmal3 : "^-?([1-9]\\d*.\\d*|0.\\d*[1-9]\\d*|0?.0+|0)$", // 浮点数
		decmal4 : "^\d+(\.\d+)?$", // 非负浮点数（正浮点数 + 0）
		decmal5 : "^((-\d+(\.\d+)?)|(0+(\.0+)?))$", // 非正浮点数（负浮点数 + 0）

		email : "^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$", // 邮件
		color : "^[a-fA-F0-9]{6}$", // 颜色
		url : "^http[s]?:\\/\\/([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?$", // url
		chinese : "^[\\u4E00-\\u9FA5\\uF900-\\uFA2D]+$", // 仅中文
		ascii : "^[\\x00-\\xFF]+$", // 仅ACSII字符
		zipcode : "^\\d{6}$", // 邮编
		mobile : "^(13|14|15|18)[0-9]{9}$", // 手机
		ip4 : "^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)$", // ip地址
		notempty : "^\\S+$", // 非空
		picture : "(.*)\\.(jpg|bmp|gif|ico|pcx|jpeg|tif|png|raw|tga)$", // 图片
		rar : "(.*)\\.(rar|zip|7zip|tgz)$", // 压缩文件
		xls : "(.*)\\.(xls|xlsx)$",
		date : "^\\d{4}(\\-|\\/|\.)\\d{1,2}\\1\\d{1,2}$", // 日期
		qq : "^[1-9]*[1-9][0-9]*$", // QQ号码
		tel : "^(([0\\+]\\d{2,3}-)?(0\\d{2,3})-)?(\\d{7,8})(-(\\d{3,}))?$", // 电话号码的函数(包括验证国内区号,国际区号,分机号)
		username : "^\\w+$", // 用来用户注册。匹配由数字、26个英文字母或者下划线组成的字符串
		letter : "^[A-Za-z]+$", // 字母
		letter_u : "^[A-Z]+$", // 大写字母
		letter_l : "^[a-z]+$", // 小写字母
		idcard : "^[1-9]([0-9]{14}|[0-9]{17})$" // 身份证
	};
	$.validate.regexEnumMsg = {
		all : "请输入",
		intege : "输入大于等于0的整数", // 整数
		intege1 : "输入大于0的整数", // 正整数
		intege2 : "输入小于0的整数", // 负整数
		num : "输入整数或带小数点的数字", // 数字
		num1 : "输入正数", // 正数（正整数 + 0）
		num2 : "输入负数", // 负数（负整数 + 0）
		decmal : "输入带小数点的数字", // 浮点数
		decmal1 : "输入带小数点的正数", // 正浮点数
		decmal2 : "输入带小数点的负数", // 负浮点数
		decmal3 : "输入带小数点的数字", // 浮点数
		decmal4 : "非负浮点数", // 非负浮点数（正浮点数 + 0）
		decmal5 : "^((-\d+(\.\d+)?)|(0+(\.0+)?))$", // 非正浮点数（负浮点数 + 0）

		email : "^输入邮箱", // 邮件
		color : "^[a-fA-F0-9]{6}$", // 颜色
		url : "^http[s]?:\\/\\/([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?$", // url
		chinese : "^[\\u4E00-\\u9FA5\\uF900-\\uFA2D]+$", // 仅中文
		ascii : "^[\\x00-\\xFF]+$", // 仅ACSII字符
		zipcode : "^\\d{6}$", // 邮编
		mobile : "输入手机号", // 手机
		ip4 : "^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)$", // ip地址
		notempty : "^\\S+$", // 非空
		picture : "(.*)\\.(jpg|bmp|gif|ico|pcx|jpeg|tif|png|raw|tga)$", // 图片
		rar : "(.*)\\.(rar|zip|7zip|tgz)$", // 压缩文件
		xls : "xls文件",
		date : "^\\d{4}(\\-|\\/|\.)\\d{1,2}\\1\\d{1,2}$", // 日期
		qq : "输入QQ号", // QQ号码
		tel : "[区号-]号码[-分机号]", // 如：[0531-]8888888[-123]，[]里的内容可选//电话号码的函数(包括验证国内区号,国际区号,分机号)
		username : "^\\w+$", // 用来用户注册。匹配由数字、26个英文字母或者下划线组成的字符串
		letter : "^[A-Za-z]+$", // 字母
		letter_u : "^[A-Z]+$", // 大写字母
		letter_l : "^[a-z]+$", // 小写字母
		idcard : "输入身份证号" // 身份证
	};
	$.fn.InputTip = function(message) {
		var self = $(this);
		self.nextAll('span.ErrorTip,span.InputTip').remove();

		var datatype = self.attr('datatype') || self.attr('required');
		if (datatype == '*')
			datatype = 'all';

		var msg = message || self.attr('inputtip')
				|| $.validate.regexEnumMsg[datatype] || "";
		// span.InputTip

		// var reqEle = self.attr('required') ? self.next('span.required') :
		// self;
		self.after('<span class="InputTip">' + msg + '</span>');
	};
	initInput();
	// $(':input[required]').parent().prev('dt').after('<span
	// class="required">*</span>');

	$.fn.validateele = function() {
		var self = $(this);
		// 移除输入提示
		$(this).validatemsg('a', true);

		var elename = self.attr['elename']
				|| $('label:first', self.parent('dd').prev('dt')).text()
						.replace(':', '').replace('：', '').replace(' ', '');

		// 检测元素有没有绑定onvalidate事件，如果绑定了则使用元素自定义的验证方案
		var event = jQuery.Event("onvalidate");
		self.trigger(event);
		if (event.result) {
			if (event.result.success)
				return true;
			else {
				self.validatemsg(event.result.msg);
				return false;
			}
		}

		// 是否跳过隐藏域的验证
		if (self.is(':hidden') && self.attr('skip') != "no")
			return true;
		var isRequired = self.attr('required');
		var datatype = self.attr('datatype');

		// 检测时间范围
		if (self.attr("tag") == "datetime" || self.attr("tag") == "datetime") {
			if (self.val() != '') {
				var option = self.getContraryDate();
				var t = option.targetInput;
				if (t.length > 0) {
					if (t.val() != '') {
						var date = self.datepicker("getDate");
						var targetdate = t.datepicker("getDate");
						if (date < targetdate != option.isMin) {
							if (option.isMin) {
								t.validatemsg("日期范围错误");
							} else {
								self.validatemsg("日期范围错误");
							}
							return false;
						}

					}
				}
			}
		}

		// 检测是否超出长度
		if (self.is("textarea")) {
			var len = self.attr('maxlength');
			if (len) {
				var str = self.val();
				if (str.length > len) {
					self.validatemsg("最多允许输入" + len + "个字符");
					return false;
				}
			}

		}

		if (!isRequired && !datatype)
			return true;
		if (!isRequired && self.val() == '')
			return true;

		if (isRequired && isRequired != '*') {
			datatype = datatype || isRequired;
		}
		var vMsg = self.attr['inputmsg'];
		if (isRequired
				&& self.is(":text,:file,input:hidden,textarea,:password")
				&& self.val() == '') {
			if (self.is(":file")) {
				self.validatemsg(vMsg || '请选择文件！');
			} else {
				self.validatemsg(vMsg || '请输入' + elename);
			}
			return false;
		} else if (self.is(':radio')) {
			var eles = $.radio(self.attr("name"));
			if (!eles.val()) {
				eles.last().validatemsg(vMsg || '请选择' + elename);
				return false;
			} else {
				return true;
			}

		} else if (self.is('select')) {
			if (self.val() == '') {
				self.validatemsg(vMsg || '请选择' + elename);
				return false;
			}
			return true;
		} else {
			if (!datatype || datatype == '*')
				return true;
			var regexpress = eval("$.validate.regexEnum." + datatype);
			if ((new RegExp(regexpress, "i")).test(self.val())) {
				return true;
			}
			self.validatemsg(elename + '输入格式不正确');
			return false;
		}
	};
	$.fn.validate = function() {
		if (this.length == 1 && this.is('form')) {
			return this.find(':input').validate();
		}
		var ret = true;
		this.each(function() {
			if (!$(this).validateele()) {
				ret = false;
				return ret;
			} else {
				if ($(this).attr('required'))
					$(this).validatemsg('a', true);
				else
					$(this).removevalidatemsg();

			}
		});
		return ret;

	};

	

	// 清空数据
	$.fn.resetInput = function() {
		var eles = $(":input", this);
		if (eles.length == 0)
			eles = this;
		return eles.each(function() {

			var self = $(this);
			if (self.is(":checkbox") || self.is(':radio'))
				return;
			if (this.name == "Id")
				self.val(0);
			else
				self.val(self.attr('defaultval') || "");
		});

	};

	// 绑定dialog数据
	$.fn.bindDlgData = function(href, callback, defaultFieldNameSpace) {
		$.waiting.show();
		this.resetInput();
		var ele = this;
		ele.resetvalidate();
		$('.edithide', ele).hide();

		$.post(href, {}, function(data) {
			$(':input[name],*[datafield]', ele).binddata(data,
					defaultFieldNameSpace);
			$.waiting.hide();
			ele.dialog('open');
			if ($.isFunction(callback)) {
				callback(data);
			}
		}, 'json');

	};

	$.fn.bindDlgHtml = function(href, callback) {
		$.waiting.show();
		var ele = this;
		ele.resetvalidate();
		$('div.content', ele).load(href, function() {
			initInput();
			$.waiting.hide();
			ele.dialog('open');
			if ($.isFunction(callback))
				callback();
		});
	};

	// TODO:修改form.submit监听方法，将 $(ele).data('submitdata')变成 <input type="hidden"
	// name="[datafield][0].[valuefield]" value="1" />
	// 传入一个对象数组，并且当前元素上有displayfield,valuefield属性,并将Value绑定到this.data('submitdata')={"[datafield][0].[valuefield]"=value1,"[datafield][1].[valuefield]"=value1}里
	$.fn.bindArray = function(data) {
		var displayfield = this.attr('displayfield');
		var strDisplay = "";
		if (displayfield) {
			for ( var i = 0; i < data.length; i++) {
				var item = data[i];
				strDisplay += $.getDataByTemplate(item, displayfield) + ",";
			}
		}
		this.val(strDisplay);
		this.toSubmitData(data);
	};
	// 将数据转换为提交数据
	$.fn.toSubmitData = function(data) {
		var valuefield = this.attr('valuefield');
		var datafield = this.attr('datafield');
		if (!valuefield)
			return false;
		this.data('selectdata', data);
		var prefix = this.attr('id') + "_data";
		$('input:hidden.' + prefix).remove();

		for ( var i = 0; i < data.length; i++) {
			var item = data[i];
			var obj = {};
			obj.name = datafield + '.' + valuefield; // +'[' + i.toString() +
														// '].' + valuefield;
			obj.value = $.getDataByTemplate(item, valuefield);
			this.after($('<input type="hidden" />').attr(obj).addClass(prefix));
		}
		// if ($.TraceEnabled) {
		// $.Trace('----------------------');
		// $('input:hidden.' + prefix).each(function() {
		// $.Trace($(this).attr('name') + ":" + $(this).val());
		// })
		// }

	};

	// 解析数据模板
	$.getDataByTemplate = function(data, template, defaultFieldNameSpace) {
		var getData = function(data, field) {
			if (defaultFieldNameSpace && field.indexOf(".") <= 0) {
				field = defaultFieldNameSpace + "." + field;
			}
			var item = data;
			var arrFields = field.split(".");
			for ( var i = 0; i < arrFields.length; i++) {
				item = item[arrFields[i]];
				if (item == null || item == undefined) {
					break;
				}
			}
			if (item == undefined) {
				item = null;
			}
			return item;
		};
		var item;
		// 替换例如 datafield="部门:{{Department.Name}}"的表达式
		var re = /\{\{([^\}]*)\}\}/g;
		if (re.test(template)) {
			item = template.replace(re, function() {
				return getData(data, arguments[1]) || "";
			});
		} else {
			// 简单的替换 datefield="Department.Name"类型的值
			item = getData(data, template);
		}
		return item;
	};

	// 绑定数据
	$.fn.binddata = function(data, defaultFieldNameSpace) {
		if (!data)
			return false;
		// 绑定数据到页面元素
		// defaultFieldPrefix,如果没有前面的名字则使用默认的名字，如"aa"则成为"name.aa","aa.bb"则不变
		return this
				.each(function() {
					var self = $(this);
					var field = $(this).attr("datafield") || this.name;

					if (field == undefined || field == null || field == "")
						return;

					var item = $.getDataByTemplate(data, field,
							defaultFieldNameSpace);

					if (self.is(':checkbox')) {
						if (item != null
								&& (item == true || item == "1" || item
										.toString().toLowerCase() == "true")) {
							self.attr("checked", true);
						} else {
							self.removeAttr("checked");
						}

					} else if (self.is(':radio')) {
						if (item != null && this.value == item.toString()) {
							self.attr("checked", true);
						}
					} else if (self.is('select')) {
						var subitem = self.children('option[value="' + item
								+ '"]');
						if (subitem.length == 0) {
							self.attr('selval', item);
						} else {
							self.removeAttr('selval').val(item);
						}
					} else {
						if (item != null) {
							// 处理日期数据
							if (item.getDate) {
								var str = item.format(self.attr('format')
										|| 'isoDate');
								if (self.is(':input'))
									self.val(str);
								else
									self.text(str);
							} else {
								if (self.is(':input')) {
									// 如果是数组并且定义了数组显示规则
									if ($.isArray(item)
											&& self.attr('displayfield'))
										self.bindArray(item);
									else
										self.val(item);
								} else {
									self.text(item);
								}
							}

						} else {
							self.val('');
						}
					}
					self.change();

				});
	};

	stripe();
});

(function() {
	function jRadio(name) {
		this.elements = $('input[type=radio][name=' + name + ']');
		this.lastVal = jRadio.prototype.val.apply(this);
	}
	jRadio.prototype.last = function() {
		return $(this.elements[this.elements.length - 1]);
	};
	jRadio.prototype.change = function(callback) {
		var self = this;
		this.elements.click(function() {
			var val = self.val();
			if (val != self.lastVal) {
				self.lastVal = val;
				callback(self);
			}
		})
	}
	jRadio.prototype.val = function(val) {
		if (val === undefined) {
			return this.elements.filter(function() {
				return this.checked;
			}).val();
		} else {
			if (this.lastVal == val)
				return;
			this.lastVal = val;
			this.elements.filter(function() {
				return $(this).val() == val;
			}).attr('checked', true);
			return this;
		}
	}

	$.radio = function(name) {
		return new jRadio(name);
	}
})();

String.prototype.isEmail = function() {
	var reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/;
	return reg.test(this);
}
String.prototype.len = function() {
	return this.replace(/[^\x00-\xff]/g, "**").length;
}

/*
 * jqURL by Josh Nathanson
 * 
 * various manipulations on url strings and windows. all functions can also take
 * a window object as an argument, for example {win:opener} but will default to
 * current window if none is passed.
 * 
 * public functions:
 * 
 * ------------------------- .url({ win:window object })
 * ------------------------- returns the whole url string like win.location.href
 * 
 * so if the current window href is "http://www.mysite.com?var1=1&var2=2&var3=3"
 * 
 * $.jqURL.url() returns "http://www.mysite.com?var1=1&var2=2&var3=3"
 * 
 * 
 * ------------------------------ .loc(urlstr:string, { win:window object,
 * w:integer, h:integer, t:integer, l:integer,
 * wintype:string('_top'[default],'_blank','_parent') ) })
 * ------------------------------ - directs passed in window to urlstr, which is
 * required - works like window.location.href = 'myurl' - but you can also use
 * it to pop open a new window by passing in "_blank" as the wintype - if
 * popping open a window, defaults to center of screen
 * 
 * so $.jqURL.loc('http://www.google.com', {w:200,h:200,wintype:'_blank'});
 * would open Google in a new centered 200x200 window
 * 
 * or, locate an url to any named window: $.jqURL.loc('http://www.google.com',{
 * win:mywindow }); opens Google in mywindow
 * 
 * 
 * ------------------------------ .qs({ ret:string('string'[default],'object'),
 * win:window object }) ------------------------------ returns querystring,
 * either string (pass ret:'string' [default]) or object (pass ret:'object')
 * 
 * so if the current window href is "http://www.mysite.com?var1=1&var2=2&var3=3"
 * 
 * $.jqURL.qs(); returns "var1=1&var2=2&var3=3"
 * 
 * $.jqURL.qs({ ret:'object' }); returns Object var1=1,var2=2,var3=3
 * 
 * 
 * ------------------------------ .strip({ keys:string(list of keys to strip),
 * win:window object }) ------------------------------ if passed with no
 * arguments, returns url with '?' and query string removed if you pass in list
 * of keys, it returns url with the specified key-value pairs removed
 * 
 * so if the current window href is "http://www.mysite.com?var1=1&var2=2&var3=3"
 * 
 * $.jqURL.strip(); will return "http://www.mysite.com"
 * 
 * $.jqURL.strip({ keys:'var1,var2' }); will return
 * "http://www.mysite.com?var3=3"
 * 
 * 
 * ------------------------------------- .get(key, {win:window object})
 * ------------------------------------- returns value of passed in querystring
 * key
 * 
 * so if the current window href is "http://www.mysite.com?var1=1&var2=2&var3=3"
 * $.jqURL.get('var2'); will return 2
 * 
 * -------------------------------------- .set(hash, {win:window object})
 * -------------------------------------- returns the window's url, but with the
 * keys/values set in the query string if the keys already exist, re-sets the
 * value if they don't exist, they're appended onto the query string
 * 
 */

jQuery.jqURL = {

	url : // returns a string
	function(args) {
		args = jQuery.extend({
			win : window
		}, args);
		return args.win.location.href;
	},

	loc : function(urlstr, args) {
		args = jQuery.extend({
			win : window,
			w : 500,
			h : 500,
			wintype : '_top'
		}, args);

		if (!args.t) {
			args.t = screen.height / 2 - args.h / 2;
		}
		if (!args.l) {
			args.l = screen.width / 2 - args.w / 2;
		}
		if (args['wintype'] == '_top') {
			args.win.location.href = urlstr;
		} else {
			open(urlstr, args['wintype'], 'width=' + args.w + ',height='
					+ args.h + ',top=' + args.t + ',left=' + args.l
					+ ',scrollbars,resizable');

		}
		return;
	},

	qs : function(args) {
		args = jQuery.extend({
			ret : 'string',
			win : window
		}, args);

		if (args['ret'] == 'string') {
			return jQuery.jqURL.url({
				win : args.win
			}).split('?')[1];
		}

		else if (args['ret'] == 'object') {

			var qsobj = {};
			var thisqs = jQuery.jqURL.url({
				win : args.win
			}).split('?')[1];

			if (thisqs) {
				var pairs = thisqs.split('&');
				for (i = 0; i < pairs.length; i++) {
					var pair = pairs[i].split('=');
					qsobj[pair[0]] = pair[1];
				}
			}
			return qsobj;
		}
	},

	strip : function(args) {
		args = jQuery.extend({
			keys : '',
			win : window
		}, args);

		if (jQuery.jqURL.url().indexOf('?') == -1) { // no query string found
			return jQuery.jqURL.url({
				win : args.win
			});
		}
		// if no keys passed in, just return url with no querystring
		else if (!args.keys) {
			return jQuery.jqURL.url({
				win : args.win
			}).split('?')[0];
		} else { // return stripped url

			var qsobj = jQuery.jqURL.qs({
				ret : 'object',
				win : args.win
			}); // object with key/value pairs
			var counter = 0;
			var url = jQuery.jqURL.url({
				win : args.win
			}).split('?')[0] + '?';
			var amp = '';

			for ( var key in qsobj) {
				if (args.keys.indexOf(key) == -1) {
					// pass test, add this key/value to string
					amp = (counter) ? '&' : '';
					url = url + amp + key + '=' + qsobj[key];
					counter++;
				}
			}
			return url;
		}
	},

	get : function(key, args) {
		args = jQuery.extend({
			win : window
		}, args);

		qsobj = jQuery.jqURL.qs({
			ret : 'object',
			win : args.win
		});
		return qsobj[key];
	},

	set : function(hash, args) {
		args = jQuery.extend({
			win : window
		}, args);

		// get current querystring
		var qsobj = jQuery.jqURL.qs({
			ret : 'object',
			win : args.win
		});

		// add/set values from hash
		for ( var i in hash) {
			qsobj[i] = hash[i];
		}

		var qstring = '';
		var counter = 0;
		var amp = '';

		// turn qsobj into string
		for ( var k in qsobj) {
			amp = (counter) ? '&' : '';
			qstring = qstring + amp + k + '=' + qsobj[k];
			counter++;
		}
		return jQuery.jqURL.strip({
			win : args.win
		}) + '?' + qstring;
	}

};

/*
 * Date Format 1.2.3 (c) 2007-2009 Steven Levithan <stevenlevithan.com> MIT
 * license
 * 
 * Includes enhancements by Scott Trenda <scott.trenda.net> and Kris Kowal
 * <cixar.com/~kris.kowal/>
 * 
 * Accepts a date, a mask, or a date and a mask. Returns a formatted version of
 * the given date. The date defaults to the current date/time. The mask defaults
 * to dateFormat.masks.default.
 */

var dateFormat = function() {
	var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, timezoneClip = /[^-+\dA-Z]/g, pad = function(
			val, len) {
		val = String(val);
		len = len || 2;
		while (val.length < len)
			val = "0" + val;
		return val;
	};

	// Regexes and supporting functions are cached through closure
	return function(date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask
		// prefix)
		if (arguments.length == 1
				&& Object.prototype.toString.call(date) == "[object String]"
				&& !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date;
		if (isNaN(date))
			throw SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var _ = utc ? "getUTC" : "get", d = date[_ + "Date"](), D = date[_
				+ "Day"](), m = date[_ + "Month"](), y = date[_ + "FullYear"](), H = date[_
				+ "Hours"](), M = date[_ + "Minutes"](), s = date[_ + "Seconds"]
				(), L = date[_ + "Milliseconds"](), o = utc ? 0 : date
				.getTimezoneOffset(), flags = {
			d : d,
			dd : pad(d),
			ddd : dF.i18n.dayNames[D],
			dddd : dF.i18n.dayNames[D + 7],
			m : m + 1,
			mm : pad(m + 1),
			mmm : dF.i18n.monthNames[m],
			mmmm : dF.i18n.monthNames[m + 12],
			yy : String(y).slice(2),
			yyyy : y,
			h : H % 12 || 12,
			hh : pad(H % 12 || 12),
			H : H,
			HH : pad(H),
			M : M,
			MM : pad(M),
			s : s,
			ss : pad(s),
			l : pad(L, 3),
			L : pad(L > 99 ? Math.round(L / 10) : L),
			t : H < 12 ? "a" : "p",
			tt : H < 12 ? "am" : "pm",
			T : H < 12 ? "A" : "P",
			TT : H < 12 ? "AM" : "PM",
			Z : utc ? "UTC" : (String(date).match(timezone) || [ "" ]).pop()
					.replace(timezoneClip, ""),
			o : (o > 0 ? "-" : "+")
					+ pad(
							Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o)
									% 60, 4),
			S : [ "th", "st", "nd", "rd" ][d % 10 > 3 ? 0
					: (d % 100 - d % 10 != 10) * d % 10]
		};

		return mask.replace(token, function($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default" : "ddd mmm dd yyyy HH:MM:ss",
	shortDate : "m/d/yy",
	mediumDate : "mmm d, yyyy",
	longDate : "mmmm d, yyyy",
	fullDate : "dddd, mmmm d, yyyy",
	shortTime : "h:MM TT",
	mediumTime : "h:MM:ss TT",
	longTime : "h:MM:ss TT Z",
	isoDate : "yyyy-mm-dd",
	isoTime : "HH:MM:ss",
	minute : "yyyy-mm-dd HH:MM",
	isoDateTime : "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime : "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames : [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sunday",
			"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
	monthNames : [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
			"Sep", "Oct", "Nov", "Dec", "January", "February", "March",
			"April", "May", "June", "July", "August", "September", "October",
			"November", "December" ]
};

// For convenience...
Date.prototype.format = function(mask, utc) {
	return dateFormat(this, mask, utc);
};

Date.MillisecondToDate = function(msd) {
	var time = parseFloat(msd) / 1000;
	if (null != time && "" != time) {
		if (time > 60 && time < 60 * 60) {
			time = parseInt(time / 60.0)
					+ "分钟"
					+ parseInt((parseFloat(time / 60.0) - parseInt(time / 60.0)) * 60)
					+ "秒";
		} else if (time >= 60 * 60 && time < 60 * 60 * 24) {
			time = parseInt(time / 3600.0)
					+ "小时"
					+ parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)
					+ "分钟"
					+ parseInt((parseFloat((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) - parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)) * 60)
					+ "秒";
		} else {
			time = parseInt(time) + "秒";
		}
	}
	return time;
};

if (!this.JSON) {

	// Create a JSON object only if one does not already exist. We create the
	// object in a closure to avoid global variables.

	JSON = function() {

		function f(n) { // Format integers to have at least two digits.
			return n < 10 ? '0' + n : n;
		}

		Date.prototype.toJSON = function() {

			// Eventually, this method will be based on the date.toISOString
			// method.

			return this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1)
					+ '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours())
					+ ':' + f(this.getUTCMinutes()) + ':'
					+ f(this.getUTCSeconds()) + 'Z';
		};

		var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g, gap, indent, meta = { // table
																			// of
																			// character
																			// substitutions
			'\b' : '\\b',
			'\t' : '\\t',
			'\n' : '\\n',
			'\f' : '\\f',
			'\r' : '\\r',
			'"' : '\\"',
			'\\' : '\\\\'
		}, rep;

		function quote(string) {

			// If the string contains no control characters, no quote
			// characters, and no
			// backslash characters, then we can safely slap some quotes around
			// it.
			// Otherwise we must also replace the offending characters with safe
			// escape
			// sequences.

			return escapeable.test(string) ? '"'
					+ string.replace(escapeable, function(a) {
						var c = meta[a];
						if (typeof c === 'string') {
							return c;
						}
						c = a.charCodeAt();
						return '\\u00' + Math.floor(c / 16).toString(16)
								+ (c % 16).toString(16);
					}) + '"' : '"' + string + '"';
		}

		function str(key, holder) {

			// Produce a string from holder[key].

			var i, // The loop counter.
			k, // The member key.
			v, // The member value.
			length, mind = gap, partial, value = holder[key];

			// If the value has a toJSON method, call it to obtain a replacement
			// value.

			if (value && typeof value === 'object'
					&& typeof value.toJSON === 'function') {
				value = value.toJSON(key);
			}

			// If we were called with a replacer function, then call the
			// replacer to
			// obtain a replacement value.

			if (typeof rep === 'function') {
				value = rep.call(holder, key, value);
			}

			// What happens next depends on the value's type.

			switch (typeof value) {
			case 'string':
				return quote(value);

			case 'number':

				// JSON numbers must be finite. Encode non-finite numbers as
				// null.

				return isFinite(value) ? String(value) : 'null';

			case 'boolean':
			case 'null':

				// If the value is a boolean or null, convert it to a string.
				// Note:
				// typeof null does not produce 'null'. The case is included
				// here in
				// the remote chance that this gets fixed someday.

				return String(value);

				// If the type is 'object', we might be dealing with an object
				// or an array or
				// null.

			case 'object':

				// Due to a specification blunder in ECMAScript, typeof null is
				// 'object',
				// so watch out for that case.

				if (!value) {
					return 'null';
				}

				// Make an array to hold the partial results of stringifying
				// this object value.

				gap += indent;
				partial = [];

				// If the object has a dontEnum length property, we'll treat it
				// as an array.

				if (typeof value.length === 'number'
						&& !(value.propertyIsEnumerable('length'))) {

					// The object is an array. Stringify every element. Use null
					// as a placeholder
					// for non-JSON values.

					length = value.length;
					for (i = 0; i < length; i += 1) {
						partial[i] = str(i, value) || 'null';
					}

					// Join all of the elements together, separated with commas,
					// and wrap them in
					// brackets.

					v = partial.length === 0 ? '[]' : gap ? '[\n' + gap
							+ partial.join(',\n' + gap) + '\n' + mind + ']'
							: '[' + partial.join(',') + ']';
					gap = mind;
					return v;
				}

				// If the replacer is an array, use it to select the members to
				// be stringified.

				if (typeof rep === 'object') {
					length = rep.length;
					for (i = 0; i < length; i += 1) {
						k = rep[i];
						if (typeof k === 'string') {
							v = str(k, value, rep);
							if (v) {
								partial.push(quote(k) + (gap ? ': ' : ':') + v);
							}
						}
					}
				} else {

					// Otherwise, iterate through all of the keys in the object.

					for (k in value) {
						v = str(k, value, rep);
						if (v) {
							partial.push(quote(k) + (gap ? ': ' : ':') + v);
						}
					}
				}

				// Join all of the member texts together, separated with commas,
				// and wrap them in braces.

				v = partial.length === 0 ? '{}' : gap ? '{\n' + gap
						+ partial.join(',\n' + gap) + '\n' + mind + '}' : '{'
						+ partial.join(',') + '}';
				gap = mind;
				return v;
			}
		}

		// Return the JSON object containing the stringify, parse, and quote
		// methods.

		return {
			stringify : function(value, replacer, space) {

				// The stringify method takes a value and an optional replacer,
				// and an optional
				// space parameter, and returns a JSON text. The replacer can be
				// a function
				// that can replace values, or an array of strings that will
				// select the keys.
				// A default replacer method can be provided. Use of the space
				// parameter can
				// produce text that is more easily readable.

				var i;
				gap = '';
				indent = '';
				if (space) {

					// If the space parameter is a number, make an indent string
					// containing that
					// many spaces.

					if (typeof space === 'number') {
						for (i = 0; i < space; i += 1) {
							indent += ' ';
						}

						// If the space parameter is a string, it will be used
						// as the indent string.

					} else if (typeof space === 'string') {
						indent = space;
					}
				}

				// If there is no replacer parameter, use the default replacer.

				if (!replacer) {
					rep = function(key, value) {
						if (!Object.hasOwnProperty.call(this, key)) {
							return undefined;
						}
						return value;
					};

					// The replacer can be a function or an array. Otherwise,
					// throw an error.

				} else if (typeof replacer === 'function'
						|| (typeof replacer === 'object' && typeof replacer.length === 'number')) {
					rep = replacer;
				} else {
					throw new Error('JSON.stringify');
				}

				// Make a fake root object containing our value under the key of
				// ''.
				// Return the result of stringifying the value.

				return str('', {
					'' : value
				});
			},

			parse : function(text, reviver) {

				// The parse method takes a text and an optional reviver
				// function, and returns
				// a JavaScript value if the text is a valid JSON text.

				var j;

				function walk(holder, key) {

					// The walk method is used to recursively walk the resulting
					// structure so
					// that modifications can be made.

					var k, v, value = holder[key];
					if (value && typeof value === 'object') {
						for (k in value) {
							if (Object.hasOwnProperty.call(value, k)) {
								v = walk(value, k);
								if (v !== undefined) {
									value[k] = v;
								} else {
									delete value[k];
								}
							}
						}
					}
					return reviver.call(holder, key, value);
				}

				// Parsing happens in three stages. In the first stage, we run
				// the text against
				// regular expressions that look for non-JSON patterns. We are
				// especially
				// concerned with '()' and 'new' because they can cause
				// invocation, and '='
				// because it can cause mutation. But just to be safe, we want
				// to reject all
				// unexpected forms.

				// We split the first stage into 4 regexp operations in order to
				// work around
				// crippling inefficiencies in IE's and Safari's regexp engines.
				// First we
				// replace all backslash pairs with '@' (a non-JSON character).
				// Second, we
				// replace all simple value tokens with ']' characters. Third,
				// we delete all
				// open brackets that follow a colon or comma or that begin the
				// text. Finally,
				// we look to see that the remaining characters are only
				// whitespace or ']' or
				// ',' or ':' or '{' or '}'. If that is so, then the text is
				// safe for eval.

				if (/^[\],:{}\s]*$/
						.test(text
								.replace(/\\["\\\/bfnrtu]/g, '@')
								.replace(
										/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
										']')
								.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

					// In the second stage we use the eval function to compile
					// the text into a
					// JavaScript structure. The '{' operator is subject to a
					// syntactic ambiguity
					// in JavaScript: it can begin a block or an object literal.
					// We wrap the text
					// in parens to eliminate the ambiguity.

					j = eval('(' + text + ')');

					// In the optional third stage, we recursively walk the new
					// structure, passing
					// each name/value pair to a reviver function for possible
					// transformation.

					return typeof reviver === 'function' ? walk({
						'' : j
					}, '') : j;
				}

				// If the text is not JSON parseable, then a SyntaxError is
				// thrown.

				throw new SyntaxError('JSON.parse');
			},

			quote : quote
		};
	}();
}
